import random
import time
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet

from goods.views import QiniuUploadAPIView
from login import models, serializers
from login.models import UserModel, UserAuthModel, UserDetailModel
from login.serializers import UserModelSerializer, UserDetailModelSerializer
from mytools import create_random_code
import re

from mytools.gitee import get_user_info, get_auth_url
from utils.myredis import r
from utils import my_sms_code
from utils.jwttool import my_jwt

import requests
import json
import uuid
from urllib.parse import quote


# Create your views here.


#图片验证码
from django.http import HttpResponse, JsonResponse
from django.shortcuts import render, redirect
from django.views import View
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator
from django.contrib.sessions.backends.db import SessionStore
from utils.imgcode import generate_captcha_text, create_captcha_image
import json


class CaptchaView(View):
    """验证码视图"""

    def get(self, request):
        # 生成验证码文本
        captcha_text = generate_captcha_text()

        # 将验证码文本存入redis
        r.set_captcha_text(captcha_text=captcha_text,time=60*60*3)

        # 创建验证码图片
        image_buffer = create_captcha_image(captcha_text)

        # 返回图片响应
        return HttpResponse(image_buffer, content_type='image/png')


@method_decorator(csrf_exempt, name='dispatch')
class VerifyCaptchaView(View):
    """验证验证码视图"""
    def post(self, request):
        # 获取请求中的验证码
        data = json.loads(request.body)
        # 获取用户输入的验证码captcha
        user_input = data.get('captcha', '').strip().upper()

        # 获取session中的验证码
        stored_captcha = r.get_captcha_text(captcha_text=user_input)
        print(stored_captcha)

        # 验证
        result = {
            'valid': user_input == stored_captcha,
            'message': '验证成功' if user_input == stored_captcha else '验证码错误'
        }

        # 无论验证是否成功，都刷新验证码
        # new_captcha_text = generate_captcha_text()
        # request.session['captcha_text'] = new_captcha_text

        # 返回值 ：：  {valid: false, message: "验证码错误"}
        return JsonResponse(result)



class SendCodeView(APIView):
    def get(self,request):
        phone=request.GET.get('phone')

        if not phone:
            return Response({'message':'手机号不能为空'},status=400)
        if not re.match(r'^1[3-9]\d{9}$',phone):
            return Response({'message':'手机号格式不正确'},status=400)
        #生成随机验证码
        code=create_random_code.MyCode()
        #发送短信验证码
        try:
            resp = my_sms_code.send_message(phone, code)
            #将验证码保存到redis中
            r.set_code(phone=phone,code=code,time=60*60*3)
            if r:
                # if resp['statusCode'] == '000000':
                    return Response({'message':'发送成功'})
                # else:
                #     return Response({'message':'发送失败'})
            else:
                return Response({'message':'redis存储失败'},status=500)
        except Exception as e:
            return Response({'message':f'发送失败{e}'},status=500)

class LoginView(APIView):
    def post(self,request):
        # 获取前端传递过来的数据
        phone=request.data.get('phone')
        password=request.data.get('password')
        code=request.data.get('code')

        #判断是否输入的参数缺失
        if not all([phone,password,code]):
            return Response({'code':400,'msg':'参数缺失'})
        #判断是手机号密码验证码是否合法
        re_phone=re.match(r'1[3-9]\d{9}',phone)
        re_password = re.match(r'^[A-Za-z0-9]{6,16}$', password)
        re_code=re.match(r'\d{4}',code)

        if not all([re_phone,re_password,re_code]):#如果有一个不合法
            return Response({'code':400,'msg':'参数不合法'})
        #判断手机号是否存在
        #从redis中读取验证码
        mycode=r.get_code(phone)

        if mycode==code:
            user = UserModel.objects.filter(phone=phone).first()  # 如果手机号存在，则返回该用户
            if user:
                if user.password == password:
                    token=my_jwt.create_token(userid=user.id,expire_seconds=60*60*24*7)
                    retoken=my_jwt.create_token(userid=user.id,expire_seconds=60*60*24*7+60*60*24*3)
                    return Response({'code': 200, 'msg': '登录成功','token':token,'retoken':retoken, 'phone': user.phone, 'userid': user.id})
                else:
                    return Response({'code': 400, 'msg': '密码或验证码错误'})
            else:
                # 如果手机号不存在，则注册
                user = UserModel.objects.create(phone=phone, password=password)
                # 创建实名认证表（只有id，其余为空）
                auth = UserAuthModel.objects.create()
                user.auth = auth

                # 创建用户详情表（只有id，其余为空）
                detail = UserDetailModel.objects.create()
                user.detail = detail

                # 保存关联关系
                user.save()
                token = my_jwt.create_token(userid=user.id, expire_seconds=60 * 60 * 24 * 7)
                retoken = my_jwt.create_token(userid=user.id, expire_seconds=60 * 60 * 24 * 7 + 60 * 60 * 24 * 3)

                return Response({'code': 200, 'msg': '注册成功','token':token,"phone": user.phone, 'userid': user.id})
        else:
           return Response({'code': 400, 'msg': '验证码错误'})


#刷新token
class RefreshTokenView(APIView):
    def post(self,request):
        token=request.data.get('token')
        if token:
            try:
                payload=my_jwt.decode(token)
                payload['exp']=int(time.time())+60*60*24*7

                return Response({'code': 200, 'msg': '刷新成功'})
            except:
                return Response({'code': 400, 'msg': 'token或retoken错误'})
        else:
            return Response({'code': 400, 'msg': 'token或retoken错误'})

#用户主动退出
class LogoutView(APIView):
    def post(self,request):
        token=request.data.get('token')
        try:
            payload=my_jwt.decode(token)
            # 计算token剩余有效时间
            expire_seconds = payload['exp'] - int(time.time())
            userid=payload['userid']
            if expire_seconds > 0:
                # 将token添加到黑名单
                r.set_code(token, userid, expire_seconds)
            else:
                return Response({'code': 400, 'msg': 'token已过期'})
        except :
            return Response({'code': 400, 'msg': 'token错误'})
                    
                    

# 配置钉钉应用信息（可以放在settings.py中）
DINGTALK_CONFIG = {
    'APP_KEY': 'dingbidnsaabhia69kxd',
    'APP_SECRET': '_mOY296tvcn2muBb0SxwTVruFy1gIg57OzJ7V-7nnWsskk2tMF7vV42sl7X8ILGe',
    'REDIRECT_URI':'http://localhost:5173/dingtalk-callback',
}

class DingTalkAuthView(APIView):
    """
    跳转到钉钉授权页面
    # 1.点击获取钉钉登录URL  点击钉钉图片跳转到登录授权页面

    """
    def get(self, request):
        state = str(uuid.uuid4())  # 防CSRF令牌
        request.session['dingtalk_state'] = state  # 存储state用于验证

        auth_url = (
            f"https://login.dingtalk.com/oauth2/auth?"
            f"response_type=code&"
            f"client_id={DINGTALK_CONFIG['APP_KEY']}&"
            f"redirect_uri={quote(DINGTALK_CONFIG['REDIRECT_URI'])}&"
            f"scope=openid&"
            f"state={state}&"
            f"prompt=consent"
        )
        return Response({'auth_url': auth_url})




class DingTalkCallbackView(APIView):
    """钉钉回调处理"""

    def get(self, request):
        code = request.GET.get('code')
        state = request.GET.get('state')

        # # 1. 验证state
        # if not request.session.get('dingtalk_state') or state != request.session.get('dingtalk_state'):
        #     return Response({'code': 400, 'msg': 'Invalid state'}, status=400)

        if not code:
            return Response({'code': 400, 'msg': 'Authorization code missing'}, status=400)

        # 2. 获取access_token
        try:
            token_data = self._get_dingtalk_token(code)
            access_token = token_data.get('accessToken')
            if not access_token:
                return Response({'code': 500, 'msg': 'Access token not found'}, status=500)
        except Exception as e:
            return Response({'code': 500, 'msg': f'Token request failed: {str(e)}'}, status=500)

        # 3. 获取用户信息
        try:
            user_data = self._get_dingtalk_user_info(access_token)
            print(user_data["mobile"])
            union_id = user_data.get('unionId')

            if not union_id:
                return Response({'code': 500, 'msg': 'Failed to get user unionId'}, status=500)
        except Exception as e:
            return Response({'code': 500, 'msg': f'User info request failed: {str(e)}'}, status=500)

        # 4. 处理用户登录/注册（不修改UserModel的方案）
        try:
            user, token_info = self._handle_user_login(union_id, user_data, user_data["mobile"])
            return Response({
                'code': 200,
                'msg': '登录成功',
                'token': token_info['token'],
                'retoken': token_info['retoken'],
                'user_info': {
                    'userid': user.id,
                    'phone': user_data["mobile"]  # 使用 token_info 中的手机号
                    # 'userid': user_data["id"]
                }
            })
        except Exception as e:
            return Response({'code': 500, 'msg': f'Login failed: {str(e)}'}, status=500)

    def _get_dingtalk_token(self, code):
        """获取钉钉access_token"""
        url = "https://api.dingtalk.com/v1.0/oauth2/userAccessToken"
        headers = {"Content-Type": "application/json"}
        data = {
            "clientId": DINGTALK_CONFIG['APP_KEY'],
            "clientSecret": DINGTALK_CONFIG['APP_SECRET'],
            "code": code,
            "grantType": "authorization_code"
        }
        response = requests.post(url, headers=headers, json=data)
        response.raise_for_status()
        return response.json()

    def _get_dingtalk_user_info(self, access_token):
        """获取钉钉用户信息"""
        url = "https://api.dingtalk.com/v1.0/contact/users/me"
        headers = {
            "Content-Type": "application/json",
            "x-acs-dingtalk-access-token": access_token
        }
        response = requests.get(url, headers=headers)
        response.raise_for_status()
        return response.json()

    def _handle_user_login(self, union_id, user_data, phone):
        """处理用户登录（不修改UserModel的方案）"""
        # 方案1：使用phone字段存储unionId（不推荐但可行）
        # user, created = UserModel.objects.get_or_create(
        #     phone=union_id,  # 使用phone字段存储unionId
        #     defaults={'password': str(uuid.uuid4())}  # 随机密码
        # )

        # 方案2：使用现有字段的某种组合（如特定格式的phone）
        # phone = random.randint(10000000000,99999999999)  # 取后11位模拟手机号
        # 判断用户表中是否有手机号用户
        user = UserModel.objects.filter(phone=phone).first()
        if not user:
            user, created = UserModel.objects.get_or_create(
                phone=phone,
                password="123456"
            )
            # 创建实名认证表（只有id，其余为空）
            auth = UserAuthModel.objects.create()
            user.auth = auth

            # 创建用户详情表（只有id，其余为空）
            detail = UserDetailModel.objects.create()
            user.detail = detail

            # 保存关联关系
            user.save()
        # 生成token
        token = my_jwt.create_token(userid=user.id)
        retoken = my_jwt.create_token(userid=user.id, expire_seconds=60 * 60 * 24 * 10)

        return user, {'token': token, 'retoken': retoken, "phone": phone}


class UserDetailAPIView(APIView):
    def get(self, request):
        phone = request.query_params.get('phone')

        if not phone:
            return Response({'code': 400, 'message': '手机号不能为空'}, status=400)

        try:
            # 获取用户对象
            user = UserModel.objects.get(phone=phone)

            # 使用序列化器将用户对象转换为JSON可序列化的数据
            serializer = UserModelSerializer(user)

            return Response({
                'code': 200,
                'message': '用户详情获取成功',
                'data': serializer.data
            })

        except UserModel.DoesNotExist:
            return Response({
                'code': 404,
                'message': '用户不存在'
            }, status=404)

    def put(self, request):
        phone = request.data.get('phone')
        if not phone:
            return Response({'code': 400, 'message': '手机号不能为空'}, status=400)

        try:
            user = UserModel.objects.get(phone=phone)
            detail_data = request.data.get('detail', {})

            # 更新用户详情
            if detail_data:
                # 如果用户还没有详情记录，则创建
                if not user.detail:
                    user.detail = UserDetailModel.objects.create()
                    user.save()

                # 更新详情字段
                for field in ['username', 'signature', 'avatar']:
                    if field in detail_data:
                        setattr(user.detail, field, detail_data[field])
                user.detail.save()

            # 返回更新后的用户数据
            serializer = UserModelSerializer(user)
            return Response({
                'code': 200,
                'message': '更新成功',
                'data': serializer.data
            })

        except UserModel.DoesNotExist:
            return Response({
                'code': 404,
                'message': '用户不存在'
            }, status=404)
        except Exception as e:
            return Response({
                'code': 500,
                'message': f'更新失败: {str(e)}'
            }, status=500)

import requests
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
import secrets
from django.contrib.auth import get_user_model
from django.contrib.auth import login as auth_login

User = get_user_model()


@csrf_exempt
def gitee_login(request):
    """
    生成Gitee授权URL
    GET /api/gitee/login/
    """
    # 生成随机state防止CSRF攻击
    state = secrets.token_urlsafe(16)
    request.session['gitee_state'] = state

    # 构建授权URL
    auth_url = get_auth_url(state)

    return JsonResponse({
        'auth_url': auth_url,
        'state': state
    })
def _handle_user_login(phone):
     """处理用户登录（不修改UserModel的方案）"""
     # 方案1：使用phone字段存储unionId（不推荐但可行）
     # user, created = UserModel.objects.get_or_create(
     #     phone=union_id,  # 使用phone字段存储unionId
     #     defaults={'password': str(uuid.uuid4())}  # 随机密码
     # )

     # 方案2：使用现有字段的某种组合（如特定格式的phone）
     # phone = random.randint(10000000000,99999999999)  # 取后11位模拟手机号
     # 判断用户表中是否有手机号用户
     user = UserModel.objects.filter(phone=phone).first()
     if not user:
         user, created = UserModel.objects.get_or_create(
             phone=phone,
             password="123456"
         )
         # 创建实名认证表（只有id，其余为空）
         auth = UserAuthModel.objects.create()
         user.auth = auth

         # 创建用户详情表（只有id，其余为空）
         detail = UserDetailModel.objects.create()
         user.detail = detail

         # 保存关联关系
         user.save()
     # 生成token
     token = my_jwt.create_token(userid=user.id)
     retoken = my_jwt.create_token(userid=user.id, expire_seconds=60 * 60 * 24 * 10)

     return user, {'token': token, 'retoken': retoken, "phone": phone}

@csrf_exempt
def gitee_callback(request):
    """
    Gitee回调接口
    GET /api/gitee/callback/
    """
    code = request.GET.get('code')
    state = request.GET.get('state')

    # 验证state参数
    if not code or not state:
        return JsonResponse({
            'code': 400,
            'message': 'Invalid request',
            'data': None
        }, status=400)

    try:
        # 1. 使用code获取用户信息
        user_info=get_user_info(code)
        user, token_info=_handle_user_login(phone=user_info["id"])
        return JsonResponse({
            'code': 200,
            'token': token_info['token'],
            'retoken': token_info['retoken'],
            'user_info': {
                'userid': user.id,
                'phone': token_info['phone']  # 使用 token_info 中的手机号
            }
        })

    except Exception as e:
        return JsonResponse({
            'code': 500,
            'message': str(e),
            'data': None
        }, status=500)


class UserAuthUpdateAPIView(APIView):
    """用户实名认证视图"""

    def post(self, request):
        # 获取请求数据
        user_id = request.data.get('user_id')
        name = request.data.get('name')
        id_number = request.data.get('id_number')
        gender = request.data.get('gender')
        ethnicity = request.data.get('ethnicity')
        birth_date_str = request.data.get('birth_date')  # 改为字符串格式
        address = request.data.get('address')

        # 打印接收到的数据用于调试
        print(f"Received data: user_id={user_id}, name={name}, id_number={id_number}, birth_date={birth_date_str}")

        # 校验必要字段
        if not user_id:
            return Response({
                'code': 400,
                'message': '缺少必要参数: user_id'
            }, status=400)

        if not name or not id_number:
            return Response({
                'code': 400,
                'message': '姓名和身份证号不能为空'
            }, status=400)

        try:
            # 处理日期格式转换
            birth_date = None
            if birth_date_str:
                # 处理 8 位数字日期格式 (如 "20050826")
                if birth_date_str.isdigit() and len(birth_date_str) == 8:
                    formatted_date = f"{birth_date_str[:4]}-{birth_date_str[4:6]}-{birth_date_str[6:8]}"
                    birth_date = formatted_date
                    print(f"Formatted birth date: {formatted_date}")
                # 尝试解析其他格式
                else:
                    try:
                        # 尝试解析 ISO 格式日期
                        birth_date = birth_date_str  # 假设已经是正确格式
                    except:
                        print(f"无法解析日期: {birth_date_str}")
                        return Response({
                            'code': 400,
                            'message': f'无效的日期格式: {birth_date_str}. 请使用 YYYY-MM-DD 格式'
                        }, status=400)

            # 获取用户对象
            user = UserModel.objects.get(id=user_id)
            print(f"Found user: {user.phone}")

            # 获取或创建实名认证记录
            if user.auth:
                # 更新已有记录
                user_auth = user.auth
                print(f"Updating existing auth record: {user_auth.id}")
            else:
                # 创建新的实名认证记录
                print("Creating new auth record")
                user_auth = UserAuthModel()
                user.auth = user_auth

            # 更新字段
            user_auth.name = name
            user_auth.id_number = id_number
            user_auth.gender = gender if gender else user_auth.gender
            user_auth.ethnicity = ethnicity if ethnicity else user_auth.ethnicity

            # 只设置有效日期
            if birth_date:
                user_auth.birth_date = birth_date

            user_auth.address = address if address else user_auth.address

            # 保存对象
            user_auth.save()
            user.save()  # 确保保存用户对象的关联

            print("Auth record saved successfully")

            # 返回成功响应
            return Response({
                'code': 200,
                'message': '实名认证更新成功',
                'data': {
                    'name': user_auth.name,
                    'id_number': user_auth.id_number,
                    'birth_date': user_auth.birth_date
                }
            })

        except UserModel.DoesNotExist:
            print(f"User not found: {user_id}")
            return Response({
                'code': 404,
                'message': '用户不存在'
            }, status=404)

        except Exception as e:
            import traceback
            error_trace = traceback.format_exc()
            print(f"Error updating auth: {error_trace}")
            return Response({
                'code': 500,
                'message': f'实名认证更新失败: {str(e)}',
                'error_details': str(e)
            }, status=500)


class UserAuthDetailAPIView(APIView):
    """查询用户实名认证信息"""

    def get(self, request):
        user_id = request.query_params.get('user_id')

        if not user_id:
            return Response({
                'code': 400,
                'message': '缺少必要参数: user_id'
            }, status=400)

        try:
            # 获取用户对象
            user = UserModel.objects.get(id=user_id)

            # 检查是否存在实名认证记录
            if not user.auth:
                return Response({
                    'code': 404,
                    'message': '未找到实名认证信息'
                }, status=404)

            user_auth = user.auth
            return Response({
                'code': 200,
                'message': '获取实名认证信息成功',
                'data': {
                    'name': user_auth.name,
                    'id_number': user_auth.id_number,
                    'gender': user_auth.gender,
                    'ethnicity': user_auth.ethnicity,
                    'birth_date': user_auth.birth_date,
                    'address': user_auth.address
                }
            })

        except UserModel.DoesNotExist:
            return Response({
                'code': 404,
                'message': '用户不存在'
            }, status=404)
        except Exception as e:
            return Response({
                'code': 500,
                'message': f'获取实名认证信息失败: {str(e)}'
            }, status=500)




# def handle_gitee_user(gitee_user_info):
#     """
#     处理Gitee用户信息
#     如果用户不存在则创建，存在则更新
#     """
#     username = f"gitee_{gitee_user_info['login']}"
#     name = gitee_user_info.get('name', username)
#
#     # 查找或创建用户
#     user, created = User.objects.get_or_create(
#         username=username,
#         defaults={
#             'first_name': name
#         }
#     )
#
#     # 更新用户信息
#     if not created:
#         user.first_name = name
#         user.save()
#
#     return user

class UserDetailUpdateAPIView(APIView):
    """用户详情更新视图"""

    def put(self, request):
        # 获取用户ID和详情数据
        phone = request.data.get('phone')
        detail_data = request.data.get('detail', {})

        if not phone:
            return Response({
                'code': 400,
                'message': '手机号不能为空'
            }, status=400)

        try:
            # 获取用户对象
            user = UserModel.objects.get(phone=phone)

            # 如果用户没有详情记录，则创建
            if not user.detail:
                user.detail = UserDetailModel.objects.create()
                user.save()

            # 更新详情字段
            detail = user.detail
            if 'username' in detail_data:
                detail.username = detail_data['username']
            if 'avatar' in detail_data:
                detail.avatar = detail_data['avatar']
            if 'signature' in detail_data:
                detail.signature = detail_data['signature']
            if 'sex' in detail_data:
                detail.sex = detail_data['sex']
            if 'birthday' in detail_data:
                # 处理日期格式
                birthday_str = detail_data['birthday']
                try:
                    if birthday_str:
                        # 尝试解析多种日期格式
                        from datetime import datetime
                        try:
                            # 尝试解析 YYYY-MM-DD 格式
                            birthday = datetime.strptime(birthday_str, '%Y-%m-%d').date()
                        except ValueError:
                            # 尝试解析 YYYY年MM月DD日 格式
                            birthday = datetime.strptime(birthday_str, '%Y年%m月%d日').date()
                        detail.birthday = birthday
                except Exception as e:
                    return Response({
                        'code': 400,
                        'message': f'生日格式错误: {str(e)}'
                    }, status=400)
            if 'address' in detail_data:
                detail.address = detail_data['address']

            # 保存更新
            detail.save()

            # 返回更新后的详情信息
            serializer = UserDetailModelSerializer(detail)
            return Response({
                'code': 200,
                'message': '用户详情更新成功',
                'data': serializer.data
            })

        except UserModel.DoesNotExist:
            return Response({
                'code': 404,
                'message': '用户不存在'
            }, status=404)
        except Exception as e:
            return Response({
                'code': 500,
                'message': f'更新失败: {str(e)}'
            }, status=500)
